package com.example.leetcode.滑动窗口;


import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 无重复字符的最长子串
 * 给定一个字符串s，请你找出其中不含有重复字符的最长子串的长度。
 * <p>
 * 示例 1:
 * 输入: s = "abcabcbb"
 * 输出: 3
 * 解释: 因为无重复字符的最长子串是 "abc"，所以其长度为 3。
 * <p>
 * 示例 2:
 * 输入: s = "bbbbb"
 * 输出: 1
 * 解释: 因为无重复字符的最长子串是 "b"，所以其长度为 1。
 * <p>
 * 滑动窗口
 * 什么是滑动窗口？
 * 其实就是一个队列,比如例题中的 abcabcbb，进入这个队列（窗口）为 abc 满足题目要求，当再进入 a，队列变成了 abca，这时候不满足要求。所以，我们要移动这个队列！
 * 如何移动？
 * 我们只要把队列的左边的元素移出就行了，直到满足题目要求！
 * 一直维持这样的队列，找出队列出现最长的长度时候，求出解！
 * <p>
 * <p>
 * 模板：
 * //外层循环扩展右边界，内层循环扩展左边界
 * for (int l = 0, r = 0 ; r < n ; r++) {
 * //当前考虑的元素
 * while (l <= r && check()) {//区间[left,right]不符合题意
 * //扩展左边界
 * }
 * //区间[left,right]符合题意，统计相关信息
 * }
 */
public class LengthOfLongestSubstring {

    public static void main(String[] args) {
        String s = "abcabcbb";
        int i = lengthOfLongestSubstring(s);
        System.out.println(i);
    }


    public static int lengthOfLongestSubstring(String s) {
        int res = 0;
        char[] chars = s.toCharArray();
        Set<Character> set = new HashSet<>();
        for (int left = 0, right = 0; right < chars.length; right++) {
            while (left <= right && set.contains(chars[right])) {
                set.remove(chars[left]);
                left++;
            }

            set.add(chars[right]);

            res = Math.max(res, right - left +1);
        }

        return res;
    }


}
